package geppetto.cat.alignments;

import geppetto.cat.common.Pair;
import geppetto.cat.corpus.BilingualCorpus;
import gnu.trove.TIntIntHashMap;
import gnu.trove.TIntObjectHashMap;

import java.io.IOException;
import java.util.ArrayList;



// Number of aligned poitns
// %aligned points vs sentence len
// Number of unaligned source words
// Number of unaligned foreign words

public class AlignmentStats {

	
	
	
	public static void printAlignmentStats(AlignmentsSet set) {
		int nrAlignedPoints = 0;
		double avgAlignedPoints = 0;

		int unalignedForeignWords = 0;
		int unalignedSourceWords = 0;
		int totalOfForeingWords = 0;
		int totalOfSourceWords = 0;
		int nrSentences = 0;
		for (Alignment a : set._alignments) {
			totalOfForeingWords += a.getForeignLenght();
			totalOfSourceWords += a.getSourceLenght();
			int alignedPoints = a.numberOfAlignedPoints();
			avgAlignedPoints += alignedPoints * 1.0 / a.getForeignLenght();
			nrAlignedPoints += alignedPoints;
			unalignedForeignWords += a.getNumberOfForeignNotAligned();
			unalignedSourceWords += a.getNumberOfSourceNotAligned();
			nrSentences++;
		}
		System.out.println("Total of points " + nrAlignedPoints);
		System.out.println("Avg of points " + avgAlignedPoints * 1.0
				/ nrSentences);
		System.out.println("Unaligned Source Words " + unalignedSourceWords
				* 1.0 / nrSentences);
		System.out.println("Unaligned Foreign Words " + unalignedForeignWords
				* 1.0 / nrSentences);
	}

	public static void statsByLen(AlignmentsSet set) {
		AlignmentsSet[] sets = set.splitBySentenceLen();
		for (int i = 0; i < sets.length; i++) {
			System.out.println(sets[i].numberOfAlignedPoints() + " "
					+ sets[i].numberOfSourceUnaligned());

		}
	}

	
	public static boolean positionValid(Alignment al, int sourceIndex, int foreignIndex, boolean all, boolean sure){
		if(all){
			return al.hasPosition(sourceIndex, foreignIndex);
		}else if(sure){
			return al.isSure(sourceIndex, foreignIndex);
		}else{
			return al.isPossible(sourceIndex, foreignIndex);
		}
	}
	
	public static void numberOfPhrases(Alignment a, TIntObjectHashMap<TIntIntHashMap> phrases, boolean all, boolean sure){
		int sourceLen = a.getSourceLenght();
		int foreignLen = a.getForeignLenght();
		for(int sourceStartIndex = 0; sourceStartIndex < sourceLen;){
			for(int foreignStartIndex = 0; foreignStartIndex < foreignLen;){				
				if(positionValid(a,sourceStartIndex, foreignStartIndex,all,sure)){
					int sourceEndIndex;
					int foreignEndIndex;
					for(sourceEndIndex = sourceStartIndex;sourceEndIndex<sourceLen;sourceEndIndex++){
						if(!positionValid(a,sourceEndIndex,foreignStartIndex,all,sure)){
							break;
						}
					}
					for(foreignEndIndex = foreignStartIndex;foreignEndIndex< foreignLen; foreignEndIndex++){
						if(!positionValid(a,sourceStartIndex,foreignEndIndex,all,sure)){
							break;
						}
					}
					int sourcePhraseLen = (sourceEndIndex-sourceStartIndex-1);
					int foreignPhraseLen = (foreignEndIndex-foreignStartIndex-1);
				//	System.out.println("Found phrase from " + sourceStartIndex + ":" + (sourceEndIndex-1) + "-" + foreignStartIndex + ":" + (foreignEndIndex-1));
					if(phrases.contains(sourcePhraseLen)){
						TIntIntHashMap is = phrases.get(sourcePhraseLen);
						if(is.contains(foreignPhraseLen)){
							is.put(foreignPhraseLen,is.get(foreignPhraseLen)+1);
						}else{
							is.put(foreignPhraseLen, 1);
						}
					}else{
						TIntIntHashMap is = new TIntIntHashMap();
						is.put(foreignPhraseLen, 1);
						phrases.put(sourcePhraseLen, is);
					}
					sourceStartIndex=sourceEndIndex-1;
					foreignStartIndex=foreignEndIndex-1;
				}
				foreignStartIndex++;
			}
			sourceStartIndex++;
		}
	}
	
	

	public static ArrayList<Pair<Pair<Integer, Integer>, Pair<Integer, Integer>>> getAllPhrases(Alignment al){
		ArrayList<Pair<Pair<Integer, Integer>, Pair<Integer, Integer>>> phrases = new ArrayList<Pair<Pair<Integer, Integer>, Pair<Integer, Integer>>>();
		int sourceLen = al.getSourceLenght();
		int foreignLen = al.getForeignLenght();	
		boolean [][] positionsCovered =   new boolean[sourceLen][foreignLen];
		
		for(int i = 0; i < sourceLen; i++){
			for(int j = 0; j < foreignLen; j++){
				positionsCovered[i][j] = false;
			}
		}	
		
		for(int foreignStartIndex = 0; foreignStartIndex < foreignLen;){
			boolean emptyForeing = true;
			for(int sourceStartIndex = 0; sourceStartIndex < sourceLen;){
				if(al.hasPosition(sourceStartIndex, foreignStartIndex) && !positionsCovered[sourceStartIndex][foreignStartIndex]){
					emptyForeing = false;
					positionsCovered[sourceStartIndex][foreignStartIndex]=true;
					int sourceEndIndex;
					int foreignEndIndex;
					for(sourceEndIndex = sourceStartIndex;sourceEndIndex<sourceLen;sourceEndIndex++){
						if(!al.hasPosition(sourceEndIndex,foreignStartIndex)){
							break;
						}
					}
					for(foreignEndIndex = foreignStartIndex;foreignEndIndex< foreignLen; foreignEndIndex++){
						if(!al.hasPosition(sourceStartIndex,foreignEndIndex)){
							break;
						}
					}
					for(int i = sourceStartIndex; i < sourceEndIndex; i++){
						for(int j = foreignStartIndex; j < foreignEndIndex; j++){
							positionsCovered[i][j]=true;
						}
					}				
					//Phrase was identified
				//	System.out.println("Found phrase from s" + sourceStartIndex + ":" + (sourceEndIndex-1) + "-t" + foreignStartIndex + ":" + (foreignEndIndex-1));	
					phrases.add(new Pair(new Pair(sourceStartIndex, (sourceEndIndex-1)), new Pair(foreignStartIndex,(foreignEndIndex-1))));
				}else{
					if(positionsCovered[sourceStartIndex][foreignStartIndex]){
						emptyForeing = false;
					}
				}
				sourceStartIndex++;
			}
			if(emptyForeing){
				phrases.add(new Pair(new Pair(-1, -1), new Pair(foreignStartIndex,foreignStartIndex)));
				//System.out.println("Found null phrase t" + foreignStartIndex);	
			}
			foreignStartIndex++;
		}
		return phrases;
	}
	
	
	
	public static TIntObjectHashMap<TIntIntHashMap> numberOfPhrases(AlignmentsSet set, boolean all, boolean sure){
		TIntObjectHashMap<TIntIntHashMap> phrases = new TIntObjectHashMap<TIntIntHashMap>();
		for(int i = 0; i < set._alignments.size(); i++){
			Alignment al = set.get(i);
			numberOfPhrases(al, phrases, all, sure);
		}
		return phrases;
	}
	
	
	public static TIntObjectHashMap<TIntIntHashMap>[] numberOfPhrasesPerSentence(AlignmentsSet set, boolean all, boolean sure){
		int numberOfSentences = set._alignments.size();
		TIntObjectHashMap<TIntIntHashMap>[] phrases = new TIntObjectHashMap[numberOfSentences];
		for(int i = 0; i < set._alignments.size(); i++){
			phrases[i] = new TIntObjectHashMap<TIntIntHashMap>();
			Alignment al = set.get(i);
			numberOfPhrases(al, phrases[i], all, sure);
		}
		return phrases;
	}
	
	
	public static class PhraseCounts{
		int nrSentences;
		int maxSourceDuration;
		int maxTargetDuration;
		double [][][] _absolutCounts;
		double _totals[];
		double[][] _max;
		double [][]  _min;
		public PhraseCounts(double[][][] absolutPhraseCounts, double[] phraseTotals, double max[][], double min[][]){
			_absolutCounts = absolutPhraseCounts;
			_totals = phraseTotals;
			_max = max;
			_min = min;
		}
		
		public double getAbsolutePhraseCount(int sentenceNumber, int sourceDuration, int targetDuration){
			return _absolutCounts[sentenceNumber][sourceDuration][targetDuration];
		}
		
		
		public double getNumberPhrases(int sentenceNumber){
			return _totals[sentenceNumber];
		}
		
		
		public double getMax(int sourceDuration, int targetDuration){
			return _max[sourceDuration][targetDuration];
		}
		public double getMin(int sourceDuration, int targetDuration){
			return _min[sourceDuration][targetDuration];
		}		
	}
	
	public static PhraseCounts getPhraseCounts (TIntObjectHashMap<TIntIntHashMap>[] phrasesPerSentence, int maxTargetLen, int maxSourceLen){
		int nrSentence = phrasesPerSentence.length;
		double [][][] absoluteCounts = new double[nrSentence][maxSourceLen][maxTargetLen];
		//double [][][] relativeCounts = new double[nrSentence][maxSourceLen][maxTargetLen];
		double totals[] = new double[nrSentence];
		double min[][] =  new double[maxSourceLen][maxTargetLen];
		double max[][] =  new double[maxSourceLen][maxTargetLen];		
		for(int td = 0; td < maxTargetLen; td++){
			for(int ts = 0; ts < maxTargetLen; ts++){
				min[ts][td] = 1000;
				max[ts][td] = -1;
			}
		}
		for(int sentenceNr = 0; sentenceNr < phrasesPerSentence.length; sentenceNr++){
			double totalPhrases = 0;	
			TIntObjectHashMap<TIntIntHashMap> phrases = phrasesPerSentence[sentenceNr];
			for(int i = 0; i < phrases.keys().length;i++){
				int sourceLen = phrases.keys()[i];
				TIntIntHashMap is = phrases.get(sourceLen);
				for(int j = 0; j < is.keys().length; j++){
					int targetLen = is.keys()[j];
					int count = is.get(targetLen);
					totalPhrases +=   count;
					if(sourceLen < maxSourceLen && targetLen < maxTargetLen){
						absoluteCounts[sentenceNr][sourceLen][targetLen] +=  count;
						if(count < min[sourceLen][targetLen]){
							min[sourceLen][targetLen] = count;
						}
						if(count > max[sourceLen][targetLen]){
							max[sourceLen][targetLen] = count;
						}
					}
					
				}
			}
			totals[sentenceNr] = totalPhrases;
		}
		return new PhraseCounts(absoluteCounts,totals,max,min);
	}
	
	
	public static class RelativePhraseCounts{
		double [][][] _relativeCounts;
		double _min[][]; 
		double _max[][]; 
		
		
		public RelativePhraseCounts(double[][][] relativePhraseCounts, double max[][], double min[][]){
			_relativeCounts = relativePhraseCounts;
			_max = max;
			_min = min;
		}
		
		public double getRelativePhraseCount(int sentenceNumber, int sourceDuration, int targetDuration){
			return _relativeCounts[sentenceNumber][sourceDuration][targetDuration];
		}
		
		
		public double getMax(int sourceDuration, int targetDuration){
			return _max[sourceDuration][targetDuration];
		}
		public double getMin(int sourceDuration, int targetDuration){
			return _min[sourceDuration][targetDuration];
		}		
	}
	
	public static RelativePhraseCounts getJointRelativePhraseCounts(PhraseCounts counts, int maxTargetLen, int maxSourceLen, int nrSentences){
		double [][][] relativeCounts = new double[nrSentences][maxSourceLen][maxTargetLen];
		double min[][] =  new double[maxSourceLen][maxTargetLen];
		double max[][] =  new double[maxSourceLen][maxTargetLen];	
		
		for(int td = 0; td < maxTargetLen; td++){
			for(int ts = 0; ts < maxTargetLen; ts++){
				min[ts][td] = 1000;
				max[ts][td] = -1;
			}
		}
		
		for(int i = 0; i < nrSentences; i++){
			for(int td = 0; td < maxTargetLen; td++){
				for(int ts = 0; ts < maxSourceLen; ts++){
					double count = counts.getAbsolutePhraseCount(i,ts,td)/counts.getNumberPhrases(i);
					if(count < min[ts][td]){
						min[ts][td] = count;
					}
					if(count > max[ts][td]){
						max[ts][td] = count;
					}
					relativeCounts[i][ts][td] = count;
				}
			}
		}
		return new RelativePhraseCounts(relativeCounts,max,min);
	}
	
	public static RelativePhraseCounts getTargetConditionRelativePhraseCounts(PhraseCounts counts, int maxTargetLen, int maxSourceLen, int nrSentences){
		double [][][] relativeCounts = new double[nrSentences][maxSourceLen][maxTargetLen];
		double min[][] =  new double[maxSourceLen][maxTargetLen];
		double max[][] =  new double[maxSourceLen][maxTargetLen];	
		
		for(int td = 0; td < maxTargetLen; td++){
			for(int ts = 0; ts < maxTargetLen; ts++){
				min[ts][td] = 1000;
				max[ts][td] = -1;
			}
		}
		
		for(int i = 0; i < nrSentences; i++){
			for(int td = 0; td < maxTargetLen; td++){
				double sum = 0;
				for(int ts = 0; ts < maxSourceLen; ts++){
					sum += counts.getAbsolutePhraseCount(i,ts,td);
				}
//				System.out.println("Sum  " + i + "td " + td + "-" + sum);
				for(int ts = 0; ts < maxSourceLen; ts++){
					double fracCount = 0;
					if(sum !=0){
						double count = counts.getAbsolutePhraseCount(i,ts,td); 
						fracCount = count /sum;
					}
					if(fracCount < min[ts][td]){
						min[ts][td] = fracCount;
					}
					if(fracCount > max[ts][td]){
						max[ts][td] = fracCount;
					}
					relativeCounts[i][ts][td] = fracCount;
				//	System.out.println("Abslotue " + i + " ts " + ts + "td " + td + "-" + counts.getAbsolutePhraseCount(i, ts, td));
				//	System.out.println("Relative " + i + " ts " + ts + "td " + td + "-" + fracCount);
				}
			}
		}
		return new RelativePhraseCounts(relativeCounts,max,min);
	}
	
	
	
	
	public static class PhraseStats{
		//Indexed by sourceLen/TargetLen
		double _mean[][];
		double _standardDeviation[][];
		public PhraseStats(double[][] mean, double[][] standardDeviation){
			_mean = mean;
			_standardDeviation = standardDeviation;
		}
		
		public double getMean(int sourceDuration, int targetDuration){
			return _mean[sourceDuration][targetDuration];
		}
		public double getStandardDeviation(int sourceDuration, int targetDuration){
			return _standardDeviation[sourceDuration][targetDuration];
		}
	}
	
	public static PhraseStats computePhrasesStats(RelativePhraseCounts counts, int maxTargetLen, int maxSourceLen, int nrSentences){
		double mean[][] = new double[maxSourceLen][maxTargetLen];
		double variance[][] =  new double[maxSourceLen][maxTargetLen];
		double standardDeviation[][] =  new double[maxSourceLen][maxTargetLen];
		
		//Sentences with zero relative frequence this don't conut to the mean.
	

		
		//double[] zeroSentences=new double[maxTargetLen];
		ArrayList<Integer>[] zeroSentences = new ArrayList[maxTargetLen];
		for(int i = 0; i< maxTargetLen; i++){
			zeroSentences[i] = new ArrayList<Integer>();
		}
		for(int sentenceNr = 0; sentenceNr < nrSentences; sentenceNr++){		
			for(int td = 0; td < maxTargetLen; td++){
				double sum=0;
				for(int ts = 0; ts < maxSourceLen; ts++){	
					double count= counts.getRelativePhraseCount(sentenceNr, ts, td);
					sum+=count;
					mean[ts][td] += count;
				}
				if(sum ==0) zeroSentences[td].add(sentenceNr);				
			}	
		}	
		for(int td = 0; td < maxTargetLen; td++){	
			for(int ts = 0; ts < maxSourceLen; ts++){
				mean[ts][td] = mean[ts][td]/(nrSentences-zeroSentences[td].size());
			}
		}
		
		for(int sentenceNr = 0; sentenceNr < nrSentences; sentenceNr++){
			for(int td = 0; td < maxTargetLen; td++){
				if(!zeroSentences[td].contains(sentenceNr)){	
					for(int ts = 0; ts < maxSourceLen; ts++){					
						variance[ts][td] +=  Math.pow(counts.getRelativePhraseCount(sentenceNr, ts, td) - mean[ts][td],2);
					}
				}
			}
		}
		for(int td = 0; td < maxTargetLen; td++){
			for(int ts = 0; ts < maxSourceLen; ts++){
				variance[ts][td] = variance[ts][td]/(nrSentences -zeroSentences[td].size());
				standardDeviation[ts][td] = Math.sqrt(variance[ts][td]);
			}
		}
		for(int td = 0; td < maxTargetLen; td++){
			for(int ts = 0; ts < maxSourceLen; ts++){
			//	System.out.println("Sentence of target " + td  + " source " + ts +  " mean " + mean[ts][td] + " variance " + variance[ts][td] + " standard deviation " + standardDeviation[ts][td]+ " min " + counts.getMin(ts,td) + " max "+  counts.getMax(ts,td));
				System.out.println(mean[ts][td] + "\t" + variance[ts][td] + "\t" + Math.sqrt(variance[ts][td])+ "\t" + counts.getMin(ts,td) + "\t"+  counts.getMax(ts,td) );
			}
		}
		System.out.println("----");
		return new AlignmentStats.PhraseStats(mean,standardDeviation);
	}
	
	public static void computedBetweenBounds(RelativePhraseCounts counts, PhraseStats stats, int maxSourceLen, int maxTargetLen, int nrSentences){
		double[][][] betweenBounds = new double[5][maxSourceLen][maxTargetLen];
		for(int td = 0; td < maxTargetLen; td++){
			for(int ts = 0; ts < maxSourceLen; ts++){
				for(int i = 1; i <= 5; i++){
					double upperBound = stats.getMean(ts,td) + 0.5*i*stats.getStandardDeviation(ts, td);
					double lowerBound = stats.getMean(ts,td) - 0.5*i*stats.getStandardDeviation(ts, td);
					for(int sentenceNr = 0; sentenceNr < nrSentences; sentenceNr++){
						double phraseAVG = counts.getRelativePhraseCount(sentenceNr, ts, td);
						if(phraseAVG <= upperBound && phraseAVG >= lowerBound){
							betweenBounds[i-1][ts][td]++;
						}
					}
					betweenBounds[i-1][ts][td] = betweenBounds[i-1][ts][td]/nrSentences;
				//	System.out.println("Sentences " +ts+ "-" +  td + " between avg + " + (0.5*i) + " standard deviation " + betweenBounds[i-1][ts][td]);
					System.out.print(betweenBounds[i-1][ts][td]+"\t");
				}
				System.out.println();
			}
			
		}
	}
	
	/**
	 * 
	 * @param set
	 * @param all
	 * @param sure
	 */
	public static void printPhrases(AlignmentsSet set,boolean all, boolean sure){
		TIntObjectHashMap<TIntIntHashMap> phrases = numberOfPhrases(set,all,sure);
		printPhrases(phrases,  all, sure);
	}
	
	public static void printPhrases(TIntObjectHashMap<TIntIntHashMap> phrases, boolean all, boolean sure){		
		System.out.println("slen | tlen | counts");
		int totalOf11= 0;
		int totalOf1n= 0;
		int totalOfn1= 0;
		int total = 0;
		int totalOf11Points = 0;
		int totalOf1nPoints = 0;
		int totalOfn1Points = 0;
		int totalOfPoints = 0;
		for(int sourceIndex = 0; sourceIndex < phrases.keys().length;sourceIndex++){
			boolean source1 = false;
			int sourceLen = phrases.keys()[sourceIndex]+1;
			if(sourceLen == 1){
				source1=true;
			}
			TIntIntHashMap is = phrases.get(sourceLen-1);
			for(int targetIndex = 0; targetIndex < is.keys().length; targetIndex++){
				int targetLen = is.keys()[targetIndex]+1;
				int numberPhrases = is.get(targetLen-1);
				if(targetLen == 1){
					if(source1){
						totalOf11 +=numberPhrases;
						totalOf11Points += numberPhrases;
					}else{
						totalOfn1 +=numberPhrases;
						totalOfn1Points += numberPhrases*targetLen*sourceLen;
					}
				}else if(source1){
					totalOf1n +=numberPhrases;
					totalOf1nPoints += numberPhrases*targetLen*sourceLen;
				}
				total+=numberPhrases;
				totalOfPoints +=numberPhrases*targetLen*sourceLen;
				//System.out.println("Phrases of source len " + phrases.keys()[i] + " foreing len of " + is.keys()[j] + " has " +is.get(is.keys()[j]) + " counts");
				System.out.println(sourceLen + "\t" + targetLen + "\t" +numberPhrases);
				
			}
		}
		System.out.println("Total of 1-1 " + totalOf11*1.0/total + " total 1-n "+  totalOf1n*1.0/total + " total n-1 " + totalOfn1*1.0/total);
		System.out.println("Total of 1-1 points" + totalOf11Points*1.0/totalOfPoints + " total 1-n "+  totalOf1nPoints*1.0/totalOfPoints + " total n-1 " + totalOfn1Points*1.0/totalOfPoints);
	}
	
	public static void main(String[] args) throws IOException {
		BilingualCorpus corpus = BilingualCorpus.getCorpusFromFileDescription(args[0], 5000,40);
		AlignmentsSet set = corpus.getAlignments(BilingualCorpus.DEV_CORPUS);
		//statsByLen(set);
		//AlignmentsSet set = new AlignmentsSet();
		
	//	PhrasePhraseHMM model = new PhrasePhraseHMM(corpus,2,2);
//		Alignment a2 = new Alignment(0, (byte) 0, 4, 4);
//		a2.add(0, 0);
//		a2.add(0, 1);
//		a2.add(1, 0);
//		a2.add(1, 1);
//	//	a2.add(2, 2);
//		a2.add(3, 3);
		//a2.add(0, 3);
		//a2.add(3, 0);
//		AlignerOutput.output(a2, System.out);
		
//		PhrasePhraseHMM model = new PhrasePhraseHMM(corpus,6,6);
//		for(Alignment al : set._alignments){
//			ArrayList<Pair<Pair<Integer, Integer>, Pair<Integer, Integer>>> phrases = AlignmentStats.getAllPhrases(al);
//			int value = model.alignmentValid(al);
//			
//		}
		
//		System.out.println("duration \t bigger than duration \t foreing pos \t cosecutive \t total impossible");
//		double[][] results= new double[7][4];
//		for(int duration = 1; duration <= 7; duration++){
//			int total = 0;
//			int bigPhrases =0;
//			int foreigPos =0;
//			int consecutiveNull=0;
//			PhrasePhraseHMM model = new PhrasePhraseHMM(corpus,duration,duration);
//			
//			for(Alignment al : set._alignments){
//			//ArrayList<Pair<Pair<Integer, Integer>, Pair<Integer, Integer>>> phrases = AlignmentStats.getAllPhrases(al);
//				int value = model.alignmentValid(al);
//				if(value == 1){
//					//AlignerOutput.output(al,corpus, System.out);
//					bigPhrases ++;
//				}else if(value == 2){
//					foreigPos++;
//				}else if(value ==3){
//					consecutiveNull++;
//				}
//				total++;
//			}
//			results[duration-1][0] = 100.0*bigPhrases/total;
//			results[duration-1][1] = 100.0*foreigPos/total;
//			results[duration-1][2] = 100.0*consecutiveNull/total;
//			results[duration-1][3] = 100.0*(bigPhrases+foreigPos+consecutiveNull)/total;
//			
////			System.out.println(" Phrases with Duration " + 100.0*bigPhrases/total);
////			System.out.println(" Phrases with foreig Pos " + 100.0*foreigPos/total);
////			System.out.println(" Phrases with consecutive nulls " + 100.0*consecutiveNull/total);
////			System.out.println(" Phrases with impossible alignments " + 100.0*(bigPhrases+foreigPos+consecutiveNull)/total);
//		}
//		System.out.println("duration \t bigger than duration \t foreing pos \t cosecutive \t total impossible");
//		for(int duration = 1; duration <= 7; duration++){
//			System.out.println(duration + "\t" + results[duration-1][0] + "\t" + results[duration-1][1] + "\t" + results[duration-1][2] +"\t" + results[duration-1][3]);
//		}
			//		System.out.println("----");
//		for(Pair<Pair<Integer, Integer>, Pair<Integer, Integer>> phrase : phrases){
//			int sourceStartIndex = phrase.first().first();
//			int sourceEndIndex = phrase.first().second();
//			int targetStartIndex = phrase.second().first();
//			int targetEndIndex = phrase.second().second();
//			if(sourceStartIndex != -1){
//				System.out.println("Found phrase from s" + sourceStartIndex + ":" + sourceEndIndex + "-t" + targetStartIndex + ":" + targetEndIndex);	
//			}else{
//				System.out.println("Found null phrase t" + targetStartIndex);	
//			}
//		}
		
		
		
		//System.out.println("max source len " + corpus.getMaxSourceLen());
		//System.out.println("max foreign len " + corpus.getMaxForeignLen());
		//TIntObjectHashMap<TIntIntHashMap> phrases = numberOfPhrases(set,false,false	);
		//for(int i = 0; i < phrases.keys().length;i++){
		//	TIntIntHashMap is = phrases.get(phrases.keys()[i]);
		//	for(int j = 0; j < is.keys().length; j++){
		//		//System.out.println("Phrases of source len " + phrases.keys()[i] + " foreing len of " + is.keys()[j] + " has " +is.get(is.keys()[j]) + " counts");
		//		System.out.println(phrases.keys()[i] + "\t" + is.keys()[j] + "\t" +is.get(is.keys()[j]));
		//	}
		
		//PrintStream out = new PrintStream(new FileOutputStream("Alignments"));
		//set.outputWithStatistics(corpus,out);
		/*
		set.outputWithStatistics(corpus,System.out);
		TIntObjectHashMap<TIntIntHashMap>[] phraseBysent = AlignmentStats.numberOfPhrasesPerSentence(set, true, true);
		PhraseCounts pc = AlignmentStats.getPhraseCounts(phraseBysent, 2, 2);
		RelativePhraseCounts rpc = AlignmentStats.getJointRelativePhraseCounts(pc, 2, 2, set._alignments.size());
		PhraseStats stats = AlignmentStats.computePhrasesStats(rpc, 2, 2,set._alignments.size());
		AlignmentStats.computedBetweenBounds(rpc, stats, 2, 2, set._alignments.size());
		
		System.out.println("Conditioned on target");
		PhraseCounts tpc = AlignmentStats.getPhraseCounts(phraseBysent, 2, 2);
		RelativePhraseCounts trpc = AlignmentStats.getTargetConditionRelativePhraseCounts(tpc, 2, 2, set._alignments.size());
		PhraseStats tstats = AlignmentStats.computePhrasesStats(trpc, 2, 2,set._alignments.size());
		AlignmentStats.computedBetweenBounds(trpc, tstats, 2, 2, set._alignments.size());
		*/
	}
}
